<template>
  <div class="task-project">
    <div class="task-search">
      <div class="search">
        <el-form class="search-form">
          <el-form-item label="负责人：">
            <el-select v-model="taskParams.userId" placeholder="请选择负责人" filterable clearable @change="getTaskManagementFn">
              <el-option v-for="item in listAllUser" :key="item.id" :label="item.name" :value="item.id" />
            </el-select>
          </el-form-item>
          <el-form-item label="任务状态：">
            <el-select
              v-model="taskParams.status"
              placeholder="请选择任务状态"
              filterable
              clearable
              @change="getTaskManagementFn"
            >
              <el-option v-for="item in getDict('taskStatus')" :key="item.id" :label="item.name" :value="item.id" />
            </el-select>
          </el-form-item>
        </el-form>
      </div>
      <div class="options">
        <el-button type="primary" :icon="Plus" @click="addTaskFn">新建</el-button>
      </div>
    </div>
    <div class="task-content">
      <Table
        class="task-table"
        :data="tableDefault.data"
        :columns="tableDefault.columns"
        :custom-content-layout="tableDefault.customContentLayout"
        @row-click="rowClickHandler"
      >
        <template #customLayout1="scope">
          <div class="percent">
            <div class="bar" :custom="scope.scope.name">
              <div class="bar-cot" :style="{ width: scope.scope.percent + '%' }"></div>
            </div>
            <span class="num">{{ scope.scope.percent || 0 }}%</span>
          </div>
        </template>
        <template #name="scope">
          <div class="common">
            <el-input
              v-if="scope.scope.isEdit"
              v-model="scope.scope.name"
              @blur="scope.scope.isEdit = false"
              @change="
                val => {
                  editChange(val, scope.scope);
                }
              "
            >
            </el-input>
            <div class="common" v-else>
              <el-tooltip
                class="box-item"
                :disabled="!isShowHoverComputed(scope.scope)"
                effect="dark"
                :content="scope.scope.name"
                placement="top"
              >
                <span class="name">
                  <i class="tool-name">{{ scope.scope.name }}</i>
                </span>
              </el-tooltip>
              <el-tooltip class="box-item" effect="dark" content="编辑" placement="top">
                <el-icon
                  @click.stop="
                    () => {
                      scope.scope.isEdit = true;
                      nextTick(() => {
                        scope.scope.tableColRef[1].querySelector('input').focus();
                      });
                    }
                  "
                  class="name-icon icon"
                >
                  <EditPen />
                </el-icon>
              </el-tooltip>
            </div>
          </div>
        </template>
        <template #status="scope">
          <UpDate class="common" type="dropdown" :config="statusConfig(scope.scope)">
            <span class="status"> {{ getDictItem("taskStatus", scope.scope.status) }}</span>
            <el-icon class="icon"><ArrowDown /></el-icon>
          </UpDate>
        </template>
        <template #userId="scope">
          <UpDate class="common" type="dropdown" :config="userConfig(scope.scope)">
            <span class="user"> {{ scope.scope.userName ? scope.scope.userName : "--" }}</span>
            <el-icon class="icon"><ArrowDown /></el-icon>
          </UpDate>
        </template>
        <template #priorityId="scope">
          <UpDate class="common" type="dropdown" :config="priorityConfig(scope.scope)">
            <span class="status"> {{ getDictItem("taskPriorityId", scope.scope.priorityId) }}</span>
            <el-icon class="icon"><ArrowDown /></el-icon>
          </UpDate>
        </template>
        <template #startTime="scope">
          <UpDate class="common" type="date" :config="startTimeConfig(scope.scope)">
            <span class="date"> {{ scope.scope.startTime ? dayJs(scope.scope.startTime).format("YYYY-MM-DD") : "--" }}</span>
            <el-icon class="icon"><Calendar /></el-icon>
          </UpDate>
        </template>
        <template #endTime="scope">
          <UpDate class="common" type="date" :config="endTimeConfig(scope.scope)">
            <span class="date"> {{ scope.scope.endTime ? dayJs(scope.scope.endTime).format("YYYY-MM-DD") : "--" }}</span>
            <el-icon class="icon"><Calendar /></el-icon>
          </UpDate>
        </template>
        <template #planStartTime="scope">
          <UpDate class="common" type="date" :config="planStartTimeConfig(scope.scope)">
            <span class="date">
              {{ scope.scope.planStartTime ? dayJs(scope.scope.planStartTime).format("YYYY-MM-DD") : "--" }}
            </span>
            <el-icon class="icon"><Calendar /></el-icon>
          </UpDate>
        </template>
        <template #planEndTime="scope">
          <UpDate class="common" type="date" :config="planEndTimeConfig(scope.scope)">
            <span class="date"> {{ scope.scope.planEndTime ? dayJs(scope.scope.planEndTime).format("YYYY-MM-DD") : "--" }}</span>
            <el-icon class="icon"><Calendar /></el-icon>
          </UpDate>
        </template>
        <template #isDelay="scope">
          <span style="width: 100%"> {{ scope.scope.isDelay ? "是" : "否" }}</span>
        </template>
      </Table>
    </div>
  </div>
  <div v-if="drawerVisible">
    <Dialog v-model:drawerVisible="drawerVisible" v-model:config="config" :project-id="projectId" @change="getTaskManagementFn">
      <template #userId="">
        <UpDate class="common-tr" type="dropdown" :config="userConfigTask">
          <template #default="scp">
            <span class="flag">
              <img v-if="scp.scope" :src="urlResource + userInfo(scp.scope).avatarUrl" />
              <div class="user-default" v-else>
                <el-icon><User /></el-icon>
              </div>
            </span>
            <span class="user" v-if="scp.scope"> {{ userInfo(scp.scope) ? userInfo(scp.scope).name : "--" }}</span>
          </template>
          <!-- <el-icon class="icon"><ArrowDown /></el-icon> -->
        </UpDate>
      </template>
    </Dialog>
  </div>
  <div v-if="isShowDetail">
    <Detail v-model:isShowDetail="isShowDetail" :id="taskId" />
  </div>
</template>
<script lang="ts" setup>
import { ref, reactive, computed, inject, onMounted, nextTick, provide } from "vue";
import { ElMessage } from "element-plus";
import { useDict } from "@/hooks/useDict";
import { Plus } from "@element-plus/icons-vue";
import Table from "@/components/Table/index.vue";
import { TableProps } from "@/components/Table/interface";
import UpDate from "../../components/UpDate/index.vue";
import Dialog from "../../components/Dialog.vue";
import Detail from "./Detail.vue";
import dayJs from "dayjs";
import { Project } from "@/api/interface/project";
// api
import { getTaskManagement, updateProjectTask, getProjectPage, addProjectTask } from "@/api/modules/project";
import { getListAllUser } from "@/api/modules/sys";
// hook
const { getDictItem, getDict } = useDict(["projectStage", "taskPriorityId", "taskStatus"]);
// 变量
const urlResource = window?.staticConfig.urlResource;
const projectId = inject("projectId");
const listAllUser = ref<any>([]);
const tableDefault: TableProps = reactive({
  data: [],
  columns: [
    {
      type: "selection",
      title: "",
      key: "",
      width: 44
    },
    {
      title: "标题",
      key: "name",
      width: 440
    },
    {
      title: "状态",
      key: "status"
    },
    {
      title: "负责人",
      key: "userId"
    },
    {
      title: "优先级",
      key: "priorityId"
    },
    {
      title: "计划开始时间",
      key: "planStartTime"
    },
    {
      title: "计划开始时间",
      key: "planEndTime"
    },
    {
      title: "实际开始",
      key: "startTime"
    },
    {
      title: "实际结束",
      key: "endTime"
    },
    {
      title: "是否延期",
      key: "isDelay"
    },
    {
      title: "延期时间",
      key: "delayTime"
    }
    // {
    //   title: "项目阶段",
    //   key: "projectStatus"
    // }
  ],
  // 层级自定义样式
  customContentLayout: [
    {
      layout: 1,
      slotName: ""
    }
  ]
});
let drawerVisible = ref(false);
let isShowDetail = ref(false);
let config = ref<any>({
  width: 40
});
let projectListParams = ref({
  currentPage: 1,
  pageSize: 1000,
  userId: "",
  searchKey: ""
});
let projectList: Project.ResProjectData = ref([]);
let taskId = ref("");
let taskParams = ref({
  projectId,
  userId: "",
  status: ""
});
// computed
const statusConfig = computed(() => data => {
  return {
    data,
    other: { options: getDict("taskStatus") },
    style: { height: 250 },
    key: "status",
    api: async params => {
      return await editChange("", params);
    },
    successCallback: () => {
      ElMessage.success("修改成功");
    }
  };
});
const userConfig = computed(() => data => {
  return {
    data,
    other: { options: listAllUser.value },
    style: { height: 250 },
    key: "userId",
    api: async params => {
      const obj = listAllUser.value.find(item => item.id == params.userId);
      if (obj) {
        params.userName = obj.name;
      }
      return await editChange("", params);
    },
    successCallback: () => {
      ElMessage.success("修改成功");
    }
  };
});
const priorityConfig = computed(() => data => {
  return {
    data,
    other: { options: getDict("taskPriorityId") },
    style: { height: 250 },
    key: "priorityId",
    api: async params => {
      return await editChange("", params);
    },
    successCallback: () => {
      ElMessage.success("修改成功");
    }
  };
});
const startTimeConfig = computed(() => data => {
  return {
    data,
    key: "startTime",
    api: async params => {
      return await editChange("", params);
    },
    attributes: {
      type: "date",
      format: "YYYY-MM-DD",
      valueFormat: "YYYY-MM-DD HH:mm:ss"
    },
    successCallback: () => {
      ElMessage.success("修改成功");
    }
  };
});
const endTimeConfig = computed(() => data => {
  return {
    data,
    key: "endTime",
    api: async params => {
      return await editChange("", params);
    },
    attributes: {
      type: "date",
      format: "YYYY-MM-DD",
      valueFormat: "YYYY-MM-DD HH:mm:ss"
    },
    successCallback: () => {
      ElMessage.success("修改成功");
    }
  };
});
const planStartTimeConfig = computed(() => data => {
  return {
    data,
    key: "planStartTime",
    api: async params => {
      return await editChange("", params);
    },
    attributes: {
      type: "date",
      format: "YYYY-MM-DD",
      valueFormat: "YYYY-MM-DD HH:mm:ss"
    },
    successCallback: () => {
      ElMessage.success("修改成功");
    }
  };
});
const planEndTimeConfig = computed(() => data => {
  return {
    data,
    key: "planEndTime",
    api: async params => {
      return await editChange("", params);
    },
    attributes: {
      type: "date",
      format: "YYYY-MM-DD",
      valueFormat: "YYYY-MM-DD HH:mm:ss"
    },
    successCallback: () => {
      ElMessage.success("修改成功");
    }
  };
});
const userInfo = computed(() => id => {
  return listAllUser.value.find(item => item.id == id);
});
// 方法
// 获取全部用户
const getListAllUserFn = async () => {
  const { data } = await getListAllUser();
  listAllUser.value = data;
};
const editChange = async (val, params) => {
  try {
    await updateProjectTask({
      id: params.id,
      remark: params.remark,
      parentId: params.parentId,
      projectId: params.projectId,
      projectName: params.projectName,
      code: params.code,
      name: params.name,
      description: params.description,
      userId: params.userId,
      userName: params.userName,
      priorityId: params.priorityId,
      planStartTime: params.planStartTime,
      planEndTime: params.planEndTime,
      startTime: params.startTime,
      endTime: params.endTime,
      stageId: params.stageId,
      markerId: params.markerId,
      status: params.status
    });
    if (val) {
      ElMessage.success("修改成功");
    }

    getTaskManagementFn();
  } catch (e) {
    console.log(e);
  }
};
const isShowHoverComputed = scope => {
  if (scope.tableColRef) {
    const childrenDom = scope.tableColRef[1].querySelector(".tool-name");
    const parantDom = scope.tableColRef[1].querySelector(".name");
    return childrenDom?.offsetWidth > parantDom?.offsetWidth;
  }
  return true;
};
// 数据转化
const getTransFormData = data => {
  let result = [];
  data.forEach((item, index) => {
    if (item.stageName) {
      const children = getTransFormData(item.parentTaskModel) || [];
      result.push({
        id: index,
        name: item.stageName,
        percent: item.percent,
        children,
        isLeaf: children.length
      });
    } else {
      const departMent = (item.relatedTasks && getTransFormData(item.relatedTasks)) || [];
      const children = [...departMent];
      result.push({
        id: item.id,
        remark: item.remark,
        gmtCreate: item.gmtCreate,
        gmtModified: item.gmtModified,
        createBy: item.createBy,
        modifiedBy: item.modifiedBy,
        parentId: item.parentId,
        projectId: item.projectId,
        projectName: item.projectName,
        code: item.code,
        name: item.name,
        description: item.description,
        userId: item.userId,
        userName: item.userName,
        priorityId: item.priorityId,
        planStartTime: item.planStartTime,
        planEndTime: item.planEndTime,
        startTime: item.startTime,
        endTime: item.endTime,
        stageId: item.stageId,
        markerId: item.markerId,
        isDelay: item.isDelay,
        delayTime: item.delayTime,
        status: item.status,
        children,
        isLeaf: children.length
      });
    }
  });
  return result;
};
const getTaskManagementFn = async () => {
  try {
    const { data } = await getTaskManagement(taskParams.value);
    // 处理数据
    tableDefault.data = getTransFormData(data);
  } catch (e) {
    console.log(e);
  }
};
// 获取某个id的任务路径
const getTaskPath = (data, id, init) => {
  data.forEach(item => {
    if (item.id == id) {
      init.unshift(item);
      getTaskPath(tableDefault.data, item.parentId, init);
    } else if (item.children) {
      getTaskPath(item.children, id, init);
    }
  });
  return init;
};
/**task */
const userConfigTask = computed(() => {
  return {
    data: { userId: "" },
    other: { options: listAllUser.value },
    style: { height: 250 },
    key: "userId",
    successCallback: data => {
      config.value.form.formData.userId = data.value.userId;
      config.value.form.formData.userName = userInfo.value(data.value.userId).name;
    }
  };
});
const addTaskFn = () => {
  drawerVisible.value = true;
  config.value.title = "新建任务";
  config.value.form = {
    formData: {
      projectId,
      name: "",
      userId: "",
      userName: "",
      priorityId: "",
      planStartTime: "",
      planEndTime: "",
      description: "",
      stageId: "",
      status: ""
    },
    rules: {
      name: [{ required: true, message: "请填写任务名称" }],
      userId: [{ required: true, message: "请选择任务负责人" }],
      planStartTime: [{ required: true, message: "请选择计划开始时间" }],
      planEndTime: [{ required: true, message: "请选择计划结束时间" }],
      projectId: [{ required: true, message: "请选择项目" }],
      priorityId: [{ required: true, message: "请选择优先级" }],
      stageId: [{ required: true, message: "请选择项目阶段" }],
      status: [{ required: true, message: "请选择任务状态" }]
    }
  };
  config.value.column = [
    {
      type: "select",
      key: "projectId",
      formItemAttribute: {
        label: "项目"
      },
      attributes: {
        placeholder: "请选择项目",
        options: projectList.value,
        multiple: false,
        filterable: true,
        clearable: true,
        disabled: true
      }
    },
    {
      type: "input",
      key: "name",
      formItemAttribute: {
        label: "任务标题"
      },
      attributes: {
        placeholder: "请填写任务标题"
      }
    },
    {
      type: "select",
      key: "status",
      formItemAttribute: {
        label: "任务状态"
      },
      attributes: {
        placeholder: "请选择任务状态",
        options: getDict("taskStatus"),
        multiple: false,
        filterable: true,
        clearable: true
      }
    },
    {
      type: "group",
      title: "",
      direction: "",
      list: [
        {
          type: "select",
          key: "stageId",
          formItemAttribute: {
            label: "项目阶段"
          },
          attributes: {
            placeholder: "请选择项目阶段",
            options: getDict("projectStage"),
            multiple: false,
            filterable: true,
            clearable: true
          }
        },
        {
          type: "select",
          key: "priorityId",
          formItemAttribute: {
            label: "优先级"
          },
          attributes: {
            placeholder: "请选择优先级",
            options: getDict("taskPriorityId"),
            multiple: false,
            filterable: true,
            clearable: true
          }
        }
      ]
    },
    {
      type: "group",
      title: "",
      direction: "",
      list: [
        {
          type: "date-picker",
          key: "planStartTime",
          formItemAttribute: {
            label: "计划开始时间"
          },
          attributes: {
            placeholder: "请选择计划开始时间",
            format: "YYYY-MM-DD",
            valueFormat: "YYYY-MM-DD HH:mm:ss"
          }
        },
        {
          type: "date-picker",
          key: "planEndTime",
          formItemAttribute: {
            label: "计划完成时间"
          },
          attributes: {
            placeholder: "请选择计划完成时间",
            format: "YYYY-MM-DD",
            valueFormat: "YYYY-MM-DD HH:mm:ss"
          }
        }
      ]
    },
    {
      type: "slot",
      key: "userId",
      formItemAttribute: {
        label: "任务负责人"
      },
      attributes: {}
    },
    {
      type: "input",
      key: "description",
      formItemAttribute: {
        label: "任务描述"
      },
      attributes: {
        placeholder: "请填写任务描述",
        type: "textarea"
      }
    }
  ];
  config.value.api = addProjectTask;
  config.value.message = "添加成功";
};
const rowClickHandler = (row: any) => {
  isShowDetail.value = true;
  taskId.value = row.id;
};
const getProjectPageFn = async () => {
  try {
    const { data } = await getProjectPage(projectListParams.value);
    projectList.value = data.records || [];
  } catch (error) {
    console.log(error);
  }
};

// provide
provide("refresh", getTaskManagementFn);
provide("getTaskPath", (id, init) => getTaskPath(tableDefault.data, id, init));

onMounted(() => {
  getTaskManagementFn();
  getListAllUserFn();
  getProjectPageFn();
});
</script>

<style lang="scss" scoped>
.task-project {
  display: flex;
  flex: 1;
  flex-flow: column nowrap;
  height: 100%;
  .task-search {
    box-sizing: border-box;
    display: flex;
    flex: 0 0 72px;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    padding: 0 30px;
    background: #ffffff;
  }
  .search-form {
    display: flex;
    align-items: center;
    width: 100%;
    .el-form-item {
      margin: 0;
      margin-right: 30px;
    }
  }
  .task-content {
    display: flex;
    flex: 1;
    margin-top: 10px;
    overflow: hidden;
    background: #ffffff;
    .task-table {
      margin-top: 48px;
      .percent {
        display: flex;
        align-items: center;
        margin-right: 30px;
        .bar {
          width: 142px;
          height: 12px;
          margin-right: 10px;
          background: var(--el-bg-color-page);
          border-radius: 11px;
          .bar-cot {
            height: 100%;
            background: $primary-color;
            border-radius: 11px;
          }
        }
        .num {
          font-size: 12px;
          color: #666666;
        }
      }
      .common {
        box-sizing: border-box;
        display: flex;
        align-items: center;
        justify-content: space-between;
        width: 100%;
        height: 100%;
        padding: 0 6px;
        cursor: pointer;
        .icon {
          display: none;
        }
        &:hover {
          .icon {
            display: block;
          }
        }
      }
      .status {
        box-sizing: border-box;
        height: 24px;
        padding: 0 18px;
        font-size: 12px;
        font-weight: 400;
        line-height: 24px;
        color: #ffffff;
        text-align: center;
        background: #5378f6;
        border-radius: 14px;
      }
      .name {
        width: 80%;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        i {
          font-style: normal;
        }
      }
      .name-icon {
        width: 24px;
      }
    }
  }
}
</style>
